package com.nightpiter.model.objects;

import java.util.ArrayList;

/**
 * Station entity class.
 * 
 * @author Ilya Shurigyn (honorik@gmail.com)
 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
 */
public class Station implements Coordinated {

	/** the Station name */
	protected String name;

	/** position on the screen */
	protected Coordinates position;

	/** geographical coordinates */
	protected Coordinates location;

	/** Schedule of working */
	protected Time openTime, closeTime;

	/** label's offset on the screen */
	protected int labelX, labelY;

	/** the angle to rotate the label around the station center */
	protected int labelAngle;

	/** indicates the label's visibility */
	protected boolean labelVisible;

	/** List of outgoing tunnels */
	protected ArrayList<Tunnel> tunnels = new ArrayList<Tunnel>();

	/** List of outgoing transfers */
	protected ArrayList<Transfer> transfers = new ArrayList<Transfer>();

	/** List of lines to that this station's tunnels belong */
	protected ArrayList<Line> lines = new ArrayList<Line>();

	/** the hub to that this station's each transfer belongs */
	protected Hub hub;

	/**
	 * public constructor
	 * 
	 * @param name -
	 *            station name
	 * @param position -
	 *            position on phone screen
	 * @param location -
	 *            location on the world map
	 * @param open -
	 *            open time
	 * @param close -
	 *            close time
	 * @param labelX -
	 *            label screen offset x
	 * @param labelY -
	 *            label screen offset y
	 * @param labelAngle -
	 *            angle to rotate the label
	 * @param labelVisible -
	 *            label visibility
	 */
	public Station(String name, Coordinates position, Coordinates location,
			Time open, Time close, int labelX, int labelY, int labelAngle,
			boolean labelVisible) {
		this.name = name;
		this.position = position;
		this.location = location;
		this.openTime = open;
		this.closeTime = close;
		this.labelX = labelX;
		this.labelY = labelY;
		this.labelAngle = labelAngle;
		this.labelVisible = labelVisible;
	}

	/**
	 * add outgoing transition to the appropriate list
	 * 
	 * package protected
	 * 
	 * @param transition
	 *            the transition to add
	 */
	void addTransition(Transition transition) {
		if (transition instanceof Tunnel) {
			this.tunnels.add((Tunnel) transition);
		}
		if (transition instanceof Transfer) {
			this.transfers.add((Transfer) transition);
		}
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @return the openTime
	 */
	public Time getOpenTime() {
		return openTime;
	}

	/**
	 * @return the closeTime
	 */
	public Time getCloseTime() {
		return closeTime;
	}

	/**
	 * @return the position
	 */
	public Coordinates getPosition() {
		return position;
	}

	/**
	 * @return the location
	 */
	public Coordinates getLocation() {
		return location;
	}

	/**
	 * @return the labelX
	 */
	public int getLabelX() {
		return labelX;
	}

	/**
	 * @return the labelY
	 */
	public int getLabelY() {
		return labelY;
	}

	/**
	 * @return the labelAngle
	 */
	public int getLabelAngle() {
		return labelAngle;
	}

	/**
	 * @return the labelVisible
	 */
	public boolean isLabelVisible() {
		return labelVisible;
	}

	/**
	 * @return the transferList
	 */
	public ArrayList<Transfer> getTransfers() {
		return transfers;
	}

	/**
	 * @return the tunnelList
	 */
	public ArrayList<Tunnel> getTunnels() {
		return tunnels;
	}

	/**
	 * @param hub
	 *            the hub to set
	 */
	public void setHub(Hub hub) {
		assert this.hub == null;
		this.hub = hub;
	}

	/**
	 * hub getter helper
	 * 
	 * @return Hub containing the station or null if the station has no
	 *         transfers
	 */
	public Hub getHub() {
		return hub;
	}

	/**
	 * register a new line
	 * 
	 * @param line
	 *            the line to add
	 */
	void addLine(Line line) {
		if (!this.lines.contains(line)) {
			this.lines.add(line);
		}
	}

	/**
	 * lines getter helper
	 * 
	 * @return array of lines to that this station's each tunnel belongs
	 */
	public ArrayList<Line> getLines() {
		return this.lines;
	}

	@Override
	public String toString() {
		return name;
	}

}
